import React, {useEffect, useState} from 'react'
import {connectComponent} from '../../../store/utils'
import {bindErrorActions, ErrorActionsType} from '../../../store/action/error'
import {Loading} from '../../../ui/loading/Loading'
import Row from '../../../ui/layout/Row'
import Col from '../../../ui/layout/Col'
import {CONSTANTS} from '../../../../constants'
import {apiPost} from '../../../api'
import {Button} from '../../../ui/button/Button'
import {LSKeys, LSMethods} from '../../../storage'
import {IResponse} from '../../../api/IResponse'
import {AuthActionsType, bindAuthActions} from '../../../store/action/auth'
import ButtonIcon from '../../../ui/icon/ButtonIcon'
import {mdiMinus, mdiPlus, mdiAlertCircle, mdiMedicalBag, mdiSilverwareForkKnife} from '@mdi/js'
import {ProductModal} from './ProductModal'
import {IMenuItem} from '../../../../api/IMenuItem'
import {CartDto} from '../../../../api/CartDto'
import {UserDto} from '../../../../api/UserDto'
import {createToast} from '../../../ui/toast/toast'
import PopoverUncontrolled from '../../../ui/popover/PopoverUncontrolled'
import Icon from '../../../ui/icon/Icon'
import {COLORS} from '../../../ui/color'

export interface MainProps {
  user: UserDto
  cart: CartDto
  authActions: AuthActionsType
  errorActions: ErrorActionsType
}

const MainContainer: React.FC<MainProps> = ({
  user,
  cart,
  authActions,
  errorActions,
}): React.ReactElement => {
  const [dish, setDish] = useState<IMenuItem | undefined>(undefined)
  const [list, setList] = useState<IMenuItem[]>(undefined)

  const loadMenu = async (): Promise<void> => {
    let token = undefined
    if (user) {
      token = LSMethods.getStorageData(LSKeys.TOKEN)
    }
    const url = CONSTANTS.apiUrl + '/menu'
    const res = await apiPost(url, {date: undefined, token: token}, {})
    const loadedList: IMenuItem[] = res.result
    setList([...loadedList])
  }

  useEffect(() => {
    loadMenu()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user])

  const writeInCart = async (newId: string, isRemove: boolean = false): Promise<void> => {
    if (!user) {
      createToast('Необходимо войти', {
        type: 'warning',
      })
    } else {
      const token = LSMethods.getStorageData(LSKeys.TOKEN)

      let newDishes = cart.dishes
      let index = newDishes.findIndex((nd) => nd.id === newId)
      if (index !== -1) {
        if (isRemove) {
          if (newDishes[index].count > 1) {
            newDishes[index].count = newDishes[index].count - 1
          } else {
            newDishes.splice(index, 1)
          }
        } else {
          newDishes[index].count = newDishes[index].count + 1
        }
      } else {
        newDishes.push({
          id: newId,
          count: 1,
        })
      }
      const res: IResponse = await apiPost(
        CONSTANTS.apiUrl + '/cart/write',
        {
          token: token,
          dishes: newDishes,
        },
        {},
      )
      authActions.setState({
        cart: {
          dishes: newDishes,
          id: cart?.id || undefined,
        } as CartDto,
      })
    }
  }

  const renderMenuList = (): React.ReactNode => {
    let items: React.ReactNode[] = []
    for (let item of list || []) {
      let newDishes = cart?.dishes || []
      let index = -1
      if (newDishes?.length > 0) {
        index = newDishes.findIndex((nd) => nd.id === item.id)
      }
      let isIncludeInCart = index !== -1
      items.push(
        <Col key={item.id} xs={12} sm={6} md={6} lg={4} xl={4} className={'d-flex'}>
          <div className={'menu-list-item'}>
            <div
              className={'menu-list-item-body'}
              onClick={(): void => {
                setDish(item)
              }}>
              <img
                className={'menu-list-item-img'}
                src={item.img ? `${CONSTANTS.apiUrl}/image/${item.id}` : '/buffet/img/bg_img.jpg'}
                alt={'Изображение блюда'}
              />
              <p className={'menu-list-item-name'}>{item.dishname}</p>
              <div className={'d-flex flex-row flex-wrap'}>
                {item.is_allergy && (
                  <>
                    <div id={`popover-${item.id}-allergens`}>
                      <Icon
                        path={mdiAlertCircle}
                        color={COLORS.red}
                        className={'mb-x4 mr-x4'}
                        size={'24px'}
                        title={''}
                      />
                    </div>
                    <PopoverUncontrolled
                      target={`popover-${item.id}-allergens`}
                      placement={'auto'}
                      trigger={'hover'}
                      size={'sm'}>
                      <p className={'mb-0'}>Есть аллерген</p>
                    </PopoverUncontrolled>
                  </>
                )}
                {item.has_vitamine && (
                  <>
                    <div id={`popover-${item.id}-vitamins`}>
                      <Icon
                        path={mdiMedicalBag}
                        color={COLORS.green}
                        size={'24px'}
                        className={'mb-x4 mr-x4'}
                      />
                    </div>
                    <PopoverUncontrolled
                      target={`popover-${item.id}-vitamins`}
                      placement={'auto'}
                      trigger={'hover'}
                      size={'sm'}>
                      <p className={'mb-0'}>Наличие витаминов</p>
                    </PopoverUncontrolled>
                  </>
                )}
                {item.diet_compatible && (
                  <>
                    <div id={`popover-${item.id}-diet_tables`}>
                      <Icon
                        path={mdiSilverwareForkKnife}
                        color={COLORS.gray700}
                        size={'24px'}
                        className={'mb-x4 mr-x4'}
                      />
                    </div>
                    <PopoverUncontrolled
                      target={`popover-${item.id}-diet_tables`}
                      placement={'auto-start'}
                      trigger={'hover'}
                      size={'sm'}>
                      <p className={'mb-0'}>Подходит под систему питания</p>
                    </PopoverUncontrolled>
                  </>
                )}
              </div>
            </div>
            <div className={'menu-list-item-footer'}>
              <div>
                <p className={'menu-list-item-weight'}>
                  Выход: {item.amount} {item.unit}
                </p>
                <p className={'menu-list-item-price'}>{item.price} &#8381;</p>
              </div>
              {isIncludeInCart && newDishes ? (
                <div className={'d-flex flex-row align-items-center justify-content-between'}>
                  <ButtonIcon
                    iconPath={mdiMinus}
                    title={''}
                    className={''}
                    isHoverArea
                    onClick={async (): Promise<void> => {
                      await writeInCart(item.id, true)
                    }}
                  />
                  <span>{newDishes[index].count}</span>
                  <ButtonIcon
                    iconPath={mdiPlus}
                    title={''}
                    className={''}
                    isHoverArea
                    onClick={async (): Promise<void> => {
                      await writeInCart(item.id, false)
                    }}
                  />
                </div>
              ) : (
                <Button
                  type={'button'}
                  onClick={async (): Promise<void> => {
                    await writeInCart(item.id)
                  }}
                  size={'md'}
                  className={'mb-0 w-100'}>
                  Купить
                </Button>
              )}
            </div>
          </div>
        </Col>,
      )
    }
    if (items.length === 0) {
      return (
        <div className={'d-flex flex-column w-100 align-items-center'}>
          <p className={'empty-menu-p'}>Заказ не доступен</p>
        </div>
      )
    } else {
      return <Row>{items}</Row>
    }
  }

  if (list) {
    return (
      <div>
        {renderMenuList()}
        {dish?.id && (
          <ProductModal
            dish={dish}
            user={user}
            cart={cart}
            writeInCart={writeInCart}
            closeModal={(): void => setDish(undefined)}
          />
        )}
      </div>
    )
  } else {
    return <Loading />
  }
}

export default connectComponent(
  (state, props) => ({
    user: state.auth.user,
    cart: state.auth.cart,
  }),
  (dispatch) => ({
    authActions: bindAuthActions(dispatch),
    errorActions: bindErrorActions(dispatch),
  }),
  MainContainer,
)
